<?php
/**
 * <https://y.st./>
 * Copyright © 2019 Alex Yst <mailto:copyright@y.st>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org./licenses/>.
**/

$xhtml = array(
	'<{title}>' => 'Usable checkpoints',
	'takedown' => '2017-11-01',
	'<{body}>' => <<<END
<section id="dreams">
	<h2>Dream journal</h2>
	<p>
		I dreamed I was trying to survive a flood.
	</p>
	<p>
		I didn&apos;t know the river was rising until I was quite a ways from home, so I didn&apos;t bring my wallet and other things I&apos;d want on me.
		It wasn&apos;t even raining, and I was just out walking around and exploring the unfamiliar area.
		I was headed to higher ground, and hit a big missing chunk in the pavement, where if I wasn&apos;t careful, I&apos;d fall into the river.
		I assessed the situation, and decided to turn back.
		I went backwards down the slope I was headed up, only to notice I&apos;d gotten wet.
		The path I&apos;d just taken was now underwater!
		At this point, I had to take the risky path to avoid the rising waters.
		I hadn&apos;t been moving upward to avoid water previously, but now that&apos;s exactly why I had to continue my ascent.
		I made it without falling, but the water was rising pretty quickly, an I had to keep moving to increasingly higher ground to avoid submersion.
	</p>
</section>
<section id="diet">
	<h2>Dietary intake</h2>
	<p>
		For breakfast, I had 39 grams of cereal and 104 grams of soy milk.
		I snacked on 138 grams of pretzels instead of having lunch, and had 621 grams of potato gnocchi, chopped carrots, and cashew sauce for dinner.
	</p>
</section>
<section id="drudgery">
	<h2>Drudgery</h2>
	<p>
		My discussion post for the day:
	</p>
	<blockquote>
		<p>
			I like how you explained what vertices, edges, and faces are.
			These are the building blocks needed to build a mesh, but I neglected to discuss what each one was myself.
			I wrote my post from the standpoint of knowing what those were already, but explaining each one would have been a better idea.
		</p>
	</blockquote>
</section>
<section id="Minetest">
	<h2>Minetest</h2>
	<img src="/img/CC_BY-SA_3.0/minetest.net./weblog/2019/07/01.png" alt="A couple checkpoints I could warp back to" class="framed-centred-image" width="1024" height="600"/>
	<p>
		I built the entire cache system, including cache-population and clearing of the cache in every situation that waranted it.
		Along the way, I realised I could simply populate the cache when a player first entered the remote checkpoint menu and clear it when they leave that menu, but decided against that route, as they may want to warp multiple times before the data became stale, and it&apos;d save time to just keep that data on hand.
	</p>
	<p>
		But then, I went to build the page that actually used that data.
		From there, I realised that the cache data needs to be modified a bit based on which checkpoint the player&apos;s currently at.
		On the remote checkpoint menu, the local checkpoint shouldn&apos;t be listed.
		The cache would have to be rebuilt when the player first accesses the menu that uses it, so it might as well remain stable throughout their time of using it.
		I needed to remove the cache-clearing code I&apos;d sprinkled throughout the file, as given that the cache-generation code would need to be rerun every time that menu opened, the cache would always be fresh if the user didn&apos;t linger in the menu, so the check for a populated cache on each page load could be removed, and having an empty cache without that check would cause a crash.
		To save processing power, the cache would be used even if it wasn&apos;t quite right, and would reflect the state of the world when the user first started browsing the remote checkpoint list, instead of when they first started using the exact subpage they were on.
		Pretty much all the code I&apos;d added today up to this point needed to be erased, though the cache-population code just needed to be moved and slightly modified.
	</p>
	<p>
		I found that Lua doesn&apos;t sort strings in a consistent way, so I had to implement character-by-character comparison.
		I didn&apos;t like the sort order though, as it claimed lower-case letters to be &quot;less than&quot; their upper-case counterparts, while the reverse would be expected, so I instead implemented comparison based on the bytes of the string.
		That provided the correct sorting order.
		I miscoded the check to see if a checkpoint is the one you&apos;re at in the cache, so I took advantage of the bug to debug the sorting order before fixing it.
		I also ended up with a strange bug in which the name of the checkpoint you&apos;d warped from got copied over the name of the checkpoint you&apos;d warped to if you had write access to that checkpoint, but that was easily fixed as well.
	</p>
	<p>
		Later, I realised that requiring players to warp back to a checkpoint if they want to release it means that they can&apos;t visit a new checkpoint with their checkpoint limit reached and hope to grab the new checkpoint.
		If they warp back to a previous checkpoint to clear it, they&apos;d have to walk all the way back to the new checkpoint.
		I think this behaviour is preferable.
		It makes it harder to juggle checkpoints and abuse the checkpoint system.
		Also, because of the way I set the local page for the checkpoint you warp to to come up and replace the remote checkpoint page as soon as you warp, it doesn&apos;t take much effort to warp to a checkpoint just to clear it as long as you&apos;re not trying to immediately go back to a checkpoint you haven&apos;t grabbed.
	</p>
	<p>
		Just before I needed to get ready for work, I couldn&apos;t resist getting the multi-page support built and the recipes for all four checkpoint types defined.
		With that, I think the checkpoint system is nearly complete.
		From here, I think the next step is modifying the checkpoint limitation to be exponentially related to how many stacks you&apos;ve mined.
		For example, perhaps the square root of the number of stacks you&apos;ve mined should be the number of checkpoints you get.
		That&apos;d do two things.
		First, it&apos;d prevent checkpoint overuse.
		Secondly, it&apos;d encourage increasing all your stats (because they separately get square rooted and added to your checkpoint count), not just focussing on something easy and getting a lot of it.
		Doing that will be easier at first, but continuing to take the easy path will eventually lead to working on other stats.
		I&apos;m not sure the best way to implement something like this though, so I may just release checkpoints as they are and tone them down in a later version.
	</p>
</section>
<section id="email">
	<h2>Blocked email</h2>
	<p>
		My email account has been blocked again.
		I didn&apos;t notice at the time, but it got blocked last night.
		In other words, it got blocked again on the same day it got unblocked.
		I&apos;ve written to my email provider again about the issue.
	</p>
</section>
END
);
